11 对象封装及属性存取
JavaScript 发展过程
JavaScript 1.0 的时候,对象不支持继承。
JavaScript 1.1 才开始具有的原型继承作为它最主要的面向对象特征。
- 向没有声明的变量名赋值,会隐式地创建一个全局变量;
- 全局变量会被绑定为全局对象(global)的属性 。
JavaScript 的变量环境(全局环境)与对象系统就关联了起来。JavaScript 也实现了带有闭包性质的函数,闭包也是环境的管理组件。闭包与对象都具有实现变量环境的能力。
在该阶段阶段,JavaScript 提出了** 对象闭包** 与 函数闭包 两个概念,并把它们用来实现的环境称为** 域(Scope)。**
JavaScript 中的对象本质上是属性集,这可以视为一个键值列表,而对象继承是由这样的列表构成的、称为原型的链。另一方面,执行的上下文就是函数或全局的变量表,这同样可以表达为一个键值列表,而执行环境也可以视为一个由该键值列表构成的链。
在 JavaScript 1.3,以及 ECMAScript ed3 的整个时代,仅仅依赖 **键值列表 **和 **基于它们的链 **实现并完善了最初的设计。
属性访问与可见性
属性的性质(attributes),即可写性、可列举性(可见性)和可配置性。ECMAScript 约定:
- “constructor”缺省是一个不可列举的属性;
- 使用赋值表达式添加属性时,属性的可列举性缺省为true。
从原型中继承来的属性
在原型继承中,在子类实例重写属性时,实际发生的行为是“在子类实例的自有属性表中添加一个新项”。不改变原型中相同属性名的值,但子类实例中的属性性质以及值覆盖原型中的。
- 数据描述符(d),d.value总是指向这个数据的值本 身;
- 存取描述符,d.get()和d.set()将分别指向属性的存取方法。
x = "abc";
console.log(x.toString());
// 自动将“值类型的字符串(“abc”)”通过包装类变成一个字符串对象
console.log(Object(x).toString());
属性存取的不确定性
JavaScript 的属性存取结果受到原型继承(链)的影响。